#pragma once

#include "LeDocumentObject/IDocumentObject.h"

#include "LeIpc7351.h"

class PackageFeature : public LDO::IDocumentObject
{
    Q_OBJECT

    Q_PROPERTY(QPointF position READ position WRITE setPosition NOTIFY positionChanged)
    Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged)
    Q_PROPERTY(L7::Anchor anchoringPoint READ anchoringPoint WRITE setAnchoringPoint NOTIFY anchoringPointChanged)

    L7::Anchor m_anchoringPoint = L7::AnchorCenter;
    qreal m_rotation = 0.0;
    QPointF m_position = QPointF(0, 0);

public:
    PackageFeature();
    ~PackageFeature();

    L7::Anchor anchoringPoint() const;
    qreal rotation() const;
    QPointF position() const;

public slots:
    void setAnchoringPoint(L7::Anchor anchoringPoint);
    void setRotation(qreal rotation);
    void setPosition(QPointF position);

signals:
    void anchoringPointChanged(L7::Anchor anchoringPoint);
    void rotationChanged(qreal rotation);
    void positionChanged(QPointF position);
};

class PackageElectricalFeature: public PackageFeature
{
    Q_OBJECT

public:
    PackageElectricalFeature();
    ~PackageElectricalFeature();
};

class PackageSurfaceTerminal : public PackageElectricalFeature
{
    Q_OBJECT

public:
    PackageSurfaceTerminal();
    ~PackageSurfaceTerminal();
};

class PackageSurfaceLeadTerminal: public PackageSurfaceTerminal
{
    Q_OBJECT

    Q_PROPERTY(qreal landingLength READ landingLength WRITE setLandingLength NOTIFY landingLengthChanged)
    Q_PROPERTY(qreal overallLength READ overallLength WRITE setOverallLength NOTIFY overallLengthChanged)
    Q_PROPERTY(qreal width READ width WRITE setWidth NOTIFY widthChanged)
    Q_PROPERTY(qreal thickness READ thickness WRITE setThickness NOTIFY thicknessChanged)

    qreal m_landingLength;
    qreal m_overallLength;
    qreal m_width;
    qreal m_thickness;

public:
    PackageSurfaceLeadTerminal();
    ~PackageSurfaceLeadTerminal();

    qreal landingLength() const;
    qreal overallLength() const;
    qreal width() const;
    qreal thickness() const;

public slots:
    void setLandingLength(qreal landingLength);
    void setOverallLength(qreal overallLength);
    void setWidth(qreal width);
    void setThickness(qreal thickness);

signals:
    void landingLengthChanged(qreal landingLength);
    void overallLengthChanged(qreal overallLength);
    void widthChanged(qreal width);
    void thicknessChanged(qreal thickness);
};

class PackageGullLeadTerminal : public PackageSurfaceLeadTerminal
{
    Q_OBJECT
public:
    PackageGullLeadTerminal();
    ~PackageGullLeadTerminal();
};

class PackageInwardLLeadTerminal : public PackageSurfaceLeadTerminal
{
    Q_OBJECT
public:
    PackageInwardLLeadTerminal();
    ~PackageInwardLLeadTerminal();
};

class PackageInwardJLeadTerminal : public PackageSurfaceLeadTerminal
{
    Q_OBJECT
public:
    PackageInwardJLeadTerminal();
    ~PackageInwardJLeadTerminal();
};

class PackageOutwardLLeadTerminal : public PackageSurfaceLeadTerminal
{
    Q_OBJECT
public:
    PackageOutwardLLeadTerminal();
    ~PackageOutwardLLeadTerminal();
};

class PackageUnderOutwardLLeadTerminal : public PackageSurfaceLeadTerminal
{
    Q_OBJECT
public:
    PackageUnderOutwardLLeadTerminal();
    ~PackageUnderOutwardLLeadTerminal();
};


/*
 * SimpleRect, FancyRect, Circle, CornerConcave
 *
 * roundcap: dia=height=width, thickness=length
 * clamp cap: length, width=bodyWidth, thickness=bodyHeight
 * rect cap: length, width=bodyWidth, thickness=bodyHeight
 *
 * TerminalBottomOnly: Rect [or DShape], thickness
 * side no lead: Rect [or DShape] => add DShape option to Rect or use CornerStyle
 *
 * TerminalBall: diameter
 * coolball, non coll ball, column: diameter
 * TBD: LGA
 *
 * corner concave: Rect with one concave in "the" corner (outer)
 *
 * flat lead: length, width, thickness
 * flat lug: Rect, thickness
 *
 * side concave: Length, width, thickness
 * side flat: Length, width, thickness
 * side convex E: Length, width, thickness
 * side convex S: Length, width, thickness
 *
 */
class PackageThroughTerminal : public PackageElectricalFeature
{
    Q_OBJECT

    // heightAboveSurface, heightBelowSurface

public:
    PackageThroughTerminal();
    ~PackageThroughTerminal();
};

class PackageMechanicalFeature : public PackageFeature
{
    Q_OBJECT

    // height, stand-off

public:
    PackageMechanicalFeature();
    ~PackageMechanicalFeature();
};

class PackageBody : public PackageMechanicalFeature
{
    Q_OBJECT

public:
    PackageBody();
    ~PackageBody();
};
